import 'dart:io';
import 'dart:typed_data';
import 'package:minio_new/minio.dart';
import 'package:flutter/foundation.dart';

class MinioService {
  late Minio _minio;
  static const String _bucketName = 'xiaosen-cloud-pan';
  
  // TODO: 配置您的MinIO服务器信息
  static const String _endpoint = 'http://51.20.9.33:9000'; // 修改为您的MinIO服务器地址
  static const String _accessKey = 'PjmZtb7icMfDkF0HeRP0'; // 修改为您的访问密钥
  static const String _secretKey = 'vVC3XqAAZE8RdkggzUoZAE2V7ULhiNUZiE7lEQVf'; // 修改为您的秘密密钥
  static const bool _useSSL = false; // 如果使用HTTPS，设置为true

  MinioService() {
    _initMinio();
  }

  void _initMinio() {
    _minio = Minio(
      endPoint: _endpoint,
      accessKey: _accessKey,
      secretKey: _secretKey,
      useSSL: _useSSL,
    );
    _ensureBucketExists();
  }

  Future<void> _ensureBucketExists() async {
    try {
      final bucketExists = await _minio.bucketExists(_bucketName);
      if (!bucketExists) {
        await _minio.makeBucket(_bucketName);
        debugPrint('Bucket $_bucketName created');
      }
    } catch (e) {
      debugPrint('Error ensuring bucket exists: $e');
    }
  }

  Future<String> uploadFile(File file, String objectName, int userId) async {
    try {
      final userObjectName = 'user_$userId/$objectName';
      await _minio.fPutObject(_bucketName, userObjectName, file.path);
      return userObjectName;
    } catch (e) {
      debugPrint('Error uploading file: $e');
      rethrow;
    }
  }

  Future<String> uploadBytes(Uint8List bytes, String objectName, int userId, {String? contentType}) async {
    try {
      final userObjectName = 'user_$userId/$objectName';
      await _minio.putObject(
        _bucketName, 
        userObjectName, 
        Stream.value(bytes),
        size: bytes.length,
        contentType: contentType,
      );
      return userObjectName;
    } catch (e) {
      debugPrint('Error uploading bytes: $e');
      rethrow;
    }
  }

  Future<Uint8List> downloadFile(String objectName) async {
    try {
      final stream = await _minio.getObject(_bucketName, objectName);
      final bytes = <int>[];
      await for (final chunk in stream) {
        bytes.addAll(chunk);
      }
      return Uint8List.fromList(bytes);
    } catch (e) {
      debugPrint('Error downloading file: $e');
      rethrow;
    }
  }

  Future<void> deleteFile(String objectName) async {
    try {
      await _minio.removeObject(_bucketName, objectName);
    } catch (e) {
      debugPrint('Error deleting file: $e');
      rethrow;
    }
  }

  Future<String> getFileUrl(String objectName, {Duration expiry = const Duration(hours: 1)}) async {
    try {
      return await _minio.presignedGetObject(_bucketName, objectName, expires: expiry.inSeconds);
    } catch (e) {
      debugPrint('Error getting file URL: $e');
      rethrow;
    }
  }

  Future<String> getUploadUrl(String objectName, {Duration expiry = const Duration(hours: 1)}) async {
    try {
      return await _minio.presignedPutObject(_bucketName, objectName, expires: expiry.inSeconds);
    } catch (e) {
      debugPrint('Error getting upload URL: $e');
      rethrow;
    }
  }

  Future<List<String>> listFiles(int userId, {String prefix = ''}) async {
    try {
      final userPrefix = 'user_$userId/$prefix';
      final objects = await _minio.listObjects(_bucketName, prefix: userPrefix).toList();
      return objects.map((obj) => obj.key!).toList();
    } catch (e) {
      debugPrint('Error listing files: $e');
      rethrow;
    }
  }

  Future<int> getFileSize(String objectName) async {
    try {
      final stat = await _minio.statObject(_bucketName, objectName);
      return stat.size ?? 0;
    } catch (e) {
      debugPrint('Error getting file size: $e');
      rethrow;
    }
  }

  Future<bool> fileExists(String objectName) async {
    try {
      await _minio.statObject(_bucketName, objectName);
      return true;
    } catch (e) {
      return false;
    }
  }
}